package org.andao.security.rest;

import java.net.URL;
import java.util.Date;

import org.andao.core.utils.ExStringUtils;
import org.andao.core.utils.SimpleBrowserMock;
import org.springframework.util.Assert;


/**
 * 基于请求签名验证的BrowserMock.<p>
 *
 * @author Seewo Software - Marco.hu(huzhiguo@cvte.cn)
 *
 */
public class SecurityBrowserMock  extends SimpleBrowserMock{

	private String username;
	private String userPrivateKey;
	private String method;
	private String date;	
	private String body = "";
	
	private SecurityBrowserMock(URL url){
		super(url);
	}
	
	public static SecurityBrowserMock instance(URL url){
		return new SecurityBrowserMock(url);
	}
	
	public SecurityBrowserMock auth(final String username,final String userPrivateKey){
		this.username = username;
		this.userPrivateKey = userPrivateKey;
		return this;
	}
		
	public SecurityBrowserMock withMethod(final String method){
		this.method = method;
		return this;
	}
	
	public SecurityBrowserMock withBody(final String body){
		setBody(body);
		this.body = body;
		return this;
	}
	
	
	public SecurityBrowserMock authenticatedResource() {
	     assertAuthentificationPossible();
	     date = String.valueOf(new Date().getTime());
	     final StringBuilder builder = new StringBuilder(username);
	     builder.append(":");
	     builder.append(HttpRequestSiningHelper.createRequestSignature(method, date, getUrl().toString(), body, userPrivateKey));//生成签名头信息
	     headers.put(HmacAttributes.X_HMAC_AUTH_SIGNATURE, builder.toString());
	     headers.put(HmacAttributes.X_HMAC_AUTH_METHOD, "HmacSHA256");
	     headers.put(HmacAttributes.X_HMAC_AUTH_DATE, date);
	     return this;
	}
	
	private void assertAuthentificationPossible() {
	     Assert.isTrue(!ExStringUtils.isBlank(username), "需要使用用户名验证");
	     Assert.isTrue(!ExStringUtils.isBlank(userPrivateKey), "需要使用用户密码作为私钥验证");
	     Assert.isTrue(!ExStringUtils.isBlank(method), "必须定义请求方法");
	     Assert.isTrue(!ExStringUtils.isBlank(getUrl().toString()), "必修定义请求的URI");
	     if (method.equalsIgnoreCase("put") || method.equalsIgnoreCase("post")) {
	         Assert.isTrue(!ExStringUtils.isBlank(body), "PUT/POST方法必须带有BODY");
	     }
	 }
}
